はじめに
Laravelは非常にDBとの関連性が深いフレームワークです。
では、どのようにDBと関わっているのでしょうか。
今回は、LaravelでDBを扱う際によく使用する Migration、Model、Seeder、Eloquent について整理していきます。
LaravelのDB関連要素について
Laravelには、DBをスムーズに扱うための素晴らしいエコシステムが用意されています。
Migration:データを格納する「家(テーブル)」
Model:「住人(または窓口)」
Seeder:初期データを運んでくる「配達人」
Eloquent:欲しいデータをピンポイントで呼び出す「インターホン」
言葉だけだとイメージしづらい部分もあるので、それぞれの詳細と「実務でどう向き合うか」を見ていきましょう。
Migration
実物のDBに対して「どんなテーブルを作るか」「どんなカラムを持たせるか」をコードで定義したものがMigration(マイグレーション)です。
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('users');
}
};
Migrationを使用する上でのポイント
直感的なメソッド指定: string() で文字列、unique() で重複不可の制約、nullable() でNULLの許可などをサクサク指定できます。
運用での便利さ: チーム開発で「このテーブル、どんな構造だっけ?」となったとき、わざわざGUIツールでDBを覗かなくても、このファイルを読めば一発で理解できます。
upとdownの対構造: php artisan migrate で up() が走り、ミスって戻したいときは down() の処理(この例ならテーブル削除)が走る仕組みです。論理削除を導入したいときは、ここに softDeletes() を足したりします。
Model
Migrationでテーブルを作ったら、次に用意するのが「Model(モデル)」です。ここが、PHPの世界とDBの世界を繋ぐ架け橋になります。
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Transaction extends Model
{
use HasFactory;
protected $fillable = [
'occurred_on',
'type',
'category_id',
'amount',
'memo',
];
protected $casts = [
'occurred_on' => 'date',
'amount' => 'integer',
];
public function category(): BelongsTo
{
return $this->belongsTo(Category::class);
}
}
Modelを使ううえでのポイント
実務では、このModelクラスを経由してあらゆるDB操作(後述のEloquentなど)を行います。
// 最もシンプルな、ID指定でのデータ取得
$transaction = Transaction::find(1);
echo $transaction->amount; // プロパティのようにカラムの値を取り出せる
また、ビジネスロジックをまとめる「Serviceクラス」などでは、上記のようにModelを静的に呼び出すだけでなく、依存性の注入(DI)を使ってコンストラクタで受け取るパターンもよく使われます。
// ServiceクラスなどでのDIの例
public function __construct(
private Transaction $transaction
) {}
public function getTransactionData($id)
{
// DIしたインスタンス経由で取得(テストが書きやすくなるメリットも)
return $this->transaction->find($id);
}
Controller、Service、Seeder、あるいはデバッグ用の php artisan tinker まで、Laravel開発においてModelを触らない日はありません。
Seeder
Migrationが空の箱(テーブル)を作るものなら、Seeder(シーダー)はその中に初期データやテストデータを流し込むための仕組みです。
<?php
namespace Database\Seeders;
use App\Models\Category;
use Illuminate\Database\Seeder;
class CategorySeeder extends Seeder
{
public function run(): void
{
$categories = [
['name' => '給与', 'type' => 'income', 'color' => '#2563eb'],
['name' => '副業', 'type' => 'income', 'color' => '#16a34a'],
['name' => '食費', 'type' => 'expense', 'color' => '#dc2626'],
['name' => '日用品', 'type' => 'expense', 'color' => '#ea580c'],
['name' => '交通費', 'type' => 'expense', 'color' => '#7c3aed'],
['name' => '娯楽', 'type' => 'expense', 'color' => '#0891b2'],
];
foreach ($categories as $category) {
Category::query()->create($category);
}
}
}
Seederを使ううえでのポイント
マスタデータの管理に最適: サービスを動かす上で必須となる「カテゴリ一覧」「権限一覧」「ステータスコード」などをGit管理し、誰の環境でも同じ初期状態を作れます。
テスト環境の構築: 大量に検証用データが欲しい場合は、Seederの中で Factory や Faker というダミーデータ生成ツールと組み合わせるのが王道です。
Seederを実務運用する上で気を付けておきたいこと
テストデータ(特にメールアドレスや電話番号など)を仕込む際、誤って本番環境や外部の通知APIと連携して「実在する宛先にテストメールが飛んでしまった!」という事故は絶対に避けたいところ。ダミーデータは安全な値(例: example.com ドメインなど)を設定する癖をつけておきましょう。
Eloquent
「生のSQLを書くの、ちょっとしんどいな…」という開発者の負担を激減させてくれるのが、Laravel自慢のORM「Eloquent(エロクアント)」です。プログラムとしてごく自然にDB操作が書けます。
$monthTransactions = Transaction::with('category')
->whereBetween('occurred_on', [
$startOfMonth->toDateString(),
$endOfMonth->toDateString(),
])
->get();
Eloquentを使用する上でのポイント
リレーションがとにかく楽: with('category') と書いておく(Eagerロード)だけで、裏側でいい感じに結合(または追跡クエリ)してくれます。データを取り出した後も、$transaction->category->name のように直感的にアクセスできます。
Collection型の恩恵: get() で取得した結果は、ただの配列ではなく「Collectionクラス」にラップされます。これが非常に強力で、PHP側でさらに map() や filter()、sum() を使ってデータを加工しやすくなります。
Eloquentを使ううえで気を付けたいこと
複雑な条件をすべてEloquentだけで解決しようとすると、メソッドチェーンやクロージャのネストが深くなり、逆に「このSQL、裏でどう動いてるんだ…?」と見づらくなることもあります。
チーム開発では、パフォーマンス(N+1問題など)を意識しつつ、「誰が見ても意図が伝わる綺麗なクエリ」を心がけるのが、脱・初心者の第一歩だったりします。
まとめ
今回は、Laravelのデータベース層を支える4つの基本要素を整理しました。
Migration でデータを迎える「家」を建て、
Model でプログラムと繋ぐ「住人」を置き、
Seeder という「配達人」に初期データを届けてもらい、
Eloquent という「インターホン」で任意のデータにアクセス。
最初は「覚えることが多くてややこしいな…」と感じるかもしれませんが、実はそれぞれが1つのアプリケーションを動かすために、役割を分担して連携し合っています。
この4つの関係性が頭の中で繋がると、新しく機能を実装するときの設計が驚くほどスムーズになり、開発がもっと楽しくなってくると思います